/*
* Copyright (c) 2007 by Kirill Kolodyazhniy.
* See the file "license.terms" for information on usage and redistribution.
*/

#ifndef _M_ROOT_H_
#define _M_ROOT_H_

#include "log.h"
#include "singleton.h"
#include "archivemanager.h"
#include "zip.h"
#include "filesystem.h"
#include "resourcemanager.h"
#include "inputsystem.h"
#include "graphic.h"
#include "gui.h"
#include "types.h"


namespace Engine
{
	/**
	*   Root object handles main engine systems(Facade).
	*/
	class Root: public Singleton<Root>
	{
	public:
		/**
		*   Initialize all systems;
		*/
		Root();

		/**
		*   Stop all systems;
		*/
		~Root();

	
		/**
		*   Start engine work. 
		*/
		void Run();				

		void OnFrameStart(unsigned long timeSinceLastFrame);
		void OnFrameEnd(unsigned long timeSinceFrameStart);
		void OnRender();
		void OnStartReset();
		void OnEndReset();

		void OnMouseMove(REAL x, REAL y);
		void OnMouseDown(InputSystem::MouseButton but);
		void OnMouseUp(InputSystem::MouseButton but);
		void OnMouseWheel(REAL val);
		void OnKeyDown(unsigned int key);
		void OnKeyUp(unsigned int key);
		void OnCharPressed(unsigned short key);

		void OnGameStart();
		void OnResumeGame();
		void OnExitGame();
		void OnQuit();		

		void OnCollision(EntityPtr entity, Vector3<REAL> pos, Vector3<REAL> normal, REAL depth);

		void SetParticlesStep(REAL val);
		
	private:						
		Log m_log;
		ArchiveManager m_archiveMngr;
		RefPtr<ZipFactory, WeakPtrExtension> m_zipFactory;
		RefPtr<FileSystemFactory, WeakPtrExtension> m_fileSystemFactory;
		ResourceManager m_resMngr;
		Graphic m_graphics;
		RefPtr<InputSystem,WeakPtrExtension> m_input;
		RenderWindowPtr m_window;
		SceneManagerPtr m_sceneManager;
		PhysicSystemPtr m_physicSystem;		
		ThreadPool      m_threadPool;

		std::map<std::string , std::pair<SceneNodePtr ,ParticleSystemPtr> > m_ps;
		
		GUI m_gui;
		CameraPtr m_camera;
		bool m_stop;

		bool m_pause;

		bool m_startGame;

		bool m_lmBut;
		Vector3<REAL> m_camPos;
		Vector3<REAL> m_camUp;
		Vector3<REAL> m_camDir;

		REAL m_camMove;
		REAL m_camStrafe;		
	};
}

#endif
